<template>
    <div class="sub-table-list-content">
        <table class='sub-table-list-table'>
            <tr>
                <th class="sub-table-list-checkbox">
                    <checkbox :checked="checkboxVal" @click="checkAll" style="transform:scale(0.7)"/>
                </th>
                <template v-for="(item,index) in metadataChildren" :key="index" >
                    <MSubTableLatticeName :item="item" :isDialog="true"></MSubTableLatticeName>
                </template>
            </tr>
            <tr v-for="(row,index) in curVal">
                <td class="sub-table-list-checkbox"
                    style="background: white;">
                    <checkbox style="transform:scale(0.7)" :checked="selectListAll.includes(row.ID_?row.ID_:row.index_)"
                              @click="selectRow(row)"/>
                </td>
                <template v-for="(item,index) in metadataChildren">
                    <td class=" sub-table-list-line-th" v-if="!item.children && subShowControl(item) && showControl(item.controlConfig,row)">
                        <m-component
                            v-model="row[item.controlConfig.field]"
                            :data="row"
                            :metadata="item.controlConfig"
                            :readOnly="true">
                        </m-component>
                    </td>
                    <td class=" sub-table-list-line-th" style="display: flex;padding: 0rem"  v-else-if="item.children && subShowControl(item) && showControl(item.controlConfig,row)">
                        <div class="m-rowChildren" v-for="rowChildren in itemChildren(item.children)">
                            <m-component
                                v-model="row[rowChildren.controlConfig.field]"
                                :data="row"
                                :metadata="rowChildren.controlConfig"
                                :readOnly="true">
                            </m-component>
                        </div>
                    </td>
                </template>
            </tr>
        </table>
        <div class="sub-empty" v-if="curVal.length==0">
            <image class="sub-empty-img" src="@/static/empty.png"/>
            <span class="sub-empty-name">{{i18n('noAnyData','暂无数据')}}</span>
        </div>
    </div>
    <rx-button-list styleFid="subTable" v-if="!readOnly" :localButtons="showButtonData" @change="handMethod"
                    label="name"></rx-button-list>
    <div v-if="show" class="sub-mobile-layer-container">
        <MSubTableLatticeDialog :metadataChildren="componentChildren" :row="subRow" :subKey="subKey" @close="close"
                                @confirm="confirm"></MSubTableLatticeDialog>
    </div>
</template>

<script>
import Util from "@/js/Util.js";
import SubTable from "./SubTable.js"
import MSubTableLatticeDialog from "./MSubTableLatticeDialog";
import MForm from '../js/MForm'
import SubTableButton from './SubTableButton'
import  MSubTableLatticeName from './MSubTableLatticeName'

export default {
    name: "MSubTableLattice",
    mixins: [SubTable, MForm,SubTableButton],
    props: ['readOnly'],
    components: {
        MSubTableLatticeDialog,
        MSubTableLatticeName
    },
    data() {
        return {
            //控件属性
            metadataChildren: this.metadata.children,
            //展示控件的属性
            componentChildren:[],
            //子表标识
            subKey: this.metadata.field,
            buttonData: [],//子表按钮
            curVal: [],
            show: false,
            subRow: {},
            selectListAll: [],//选中行id
            checkboxVal: false,
            selectRowLise: [],//选中行数据
            cacheCalc:{
                //[row.index_]:watchCalc()
            },
            ctlType:{}
        }
    },
    created() {
        this.init(this.metadata.children);
        this.initButtonData();
        this.getCtlType()
    },
    methods: {
        i18n(name,text,key){
            return this.$ti18(name,text,"componentsLang",key);
        },
        init(list){
            list.forEach(res=>{
                if(res.children){
                    this.init(res.children)
                }else {
                    this.componentChildren.push(res)
                }
            })
        },
        itemChildren(list,dataList){
            if(!dataList){
                dataList = []
            }
            list.forEach(res=>{
                if(res.children){
                    this.itemChildren(res.children,dataList)
                }else {
                    dataList.push(res)
                }
            })
            return dataList
        },
        subShowControl(item){
            let conditionConfig = item.colHideConfig;
            if (!conditionConfig) {
                return true;
            }
            if(conditionConfig.isHide){
                return false
            }
            if(!conditionConfig.hideCondition){
                return true;
            }
            let {hideCondition} = conditionConfig;
            if (hideCondition.indexOf('return') === -1) {
                hideCondition = 'return ' + hideCondition;
            }
            debugger
            let fn = new Function('row',hideCondition);
            return  !fn.call(this,this.data)
        },
        // 全选
        checkAll() {
            this.checkboxVal = !this.checkboxVal;
            if (this.checkboxVal) {
                this.curVal.forEach(res => {
                    this.selectListAll.push(res.ID_?res.ID_:res.index_)
                    this.selectRowLise.push(res)
                })
            } else {
                this.selectListAll = [];
                this.selectRowLise = []
            }
        },
        selectRow(row) {
            let idShow = true
            this.selectListAll.forEach((res, index) => {
                let id = row.ID_?row.ID_:row.index_
                if (res == id) {
                    this.selectListAll.splice(index, 1)
                    this.selectRowLise.splice(index, 1)
                    idShow = false
                }
            })
            if (idShow) {
                this.selectRowLise.push(row)
                this.selectListAll.push(row.ID_?row.ID_:row.index_)
            }
        },
        getCtlType(){
            this.metadataChildren.forEach(row=>{
                let item = row['controlConfig']
                if(item.type === 'number'){
                    this.ctlType[item.field] = item.options.decimalLength || 0
                }
            })
        },
        calcVal(calc,row){
            let pattern = /data\[\S.*?\]\[rowIndex\]/g;
            calc = calc.replace(pattern, ()=>{
                return 'row'
            });
            if(!calc.includes('return ')){
                calc =`return ${calc}`
            }
            let fn = new Function('row','data',calc).call(this.formVm,row,this.data);
            if(typeof fn === "function"){
                /*如果是在js脚本里面写方法 例如 calc:'this.myFn' js-> myFn(obj){} */
                return fn.call(this.formVm,{
                    row,
                    data:this.formVm.data,
                    rowIndex:''
                })
            }else {
                return fn ;
            }
        },
        /**
         * 返回值
         * */
        calcFormula(row,formula,key){
            let  { condition ,calc} = formula
            if(condition){
                let fn = this.calcVal(condition,row)
                if(fn){
                    if(Reflect.has(this.ctlType,key)){
                        return Util.roundToPrecision(Number(this.calcVal(calc,row)), this.ctlType[key])
                    }
                    return this.calcVal(calc,row)
                }
            }else if(calc){
                if(Reflect.has(this.ctlType,key)){
                    return Util.roundToPrecision(Number(this.calcVal(calc,row)), this.ctlType[key])
                }
                return this.calcVal(calc,row)
            }
            return ''
        },
        watchValue(row){
            let { formulas:{subTable} } = this.formVm ;
            let calc = subTable[this.subKey];
            for (let key in calc){
                let rowKey = `${row.index_}_${key}`;
                if(Reflect.has(row,key) && !this.cacheCalc[rowKey]){
                    this.cacheCalc[rowKey] = this.$watch(()=>{
                        return this.calcFormula(row,calc[key],key)
                    },(v)=>{
                        row[key] = v
                    },{
                        deep:true
                    })
                }
            }
        },
        //子表添加
        add() {
            let initData = this.data.initData[this.subKey];
            let row = JSON.parse(JSON.stringify(initData));
            row.index_ = Util.randomId();
            this.subRow = row;
            this.show = true ;
            this.watchValue(this.subRow)
        },
        //删除
        delete() {
            if (this.selectListAll.length == 0) {
                this.$message.warning(this.i18n('oneRow','请至少选中一行数据！'));
                return
            }
            let self = this;
            uni.showModal({
                title: this.$ti18('rxMsa.tips', '提示'),
                content:this.i18n('sureDelete','确定删除？'),
                confirmText: this.$ti18('rxForm.okBtn', '确定'),
                cancelText: this.$ti18('rxForm.cancelBtn', '取消'),
                success: function (res) {
                    if (res.confirm) {
                        for (let i = self.curVal.length - 1; i >= 0; i--) {
                            let row = self.curVal[i];
                            if (self.selectListAll.includes(row.ID_?row.ID_:row.index_)) {
                                for (let k in Util.deepClone(self.cacheCalc)){
                                    if(k.includes(row.index_)){
                                        Reflect.deleteProperty(self.cacheCalc,k)
                                    }
                                }
                                self.curVal.splice(i, 1);
                            }
                        }
                        self.selectListAll = [];
                        self.selectRowLise = []
                    }
                }
            });
        },
        //上移
        upMove() {
            if (this.selectRowLise.length === 0) {
                this.$message.warning(this.i18n('oneRow','请至少选中一行数据！'));
                return;
            }
            if (this.selectRowLise.length > 1) {
                let area = this.getContinuousIndex();
                if (area) {
                    let [idx, lastIdx] = area;
                    let arr = []
                    while (lastIdx >= idx) {
                        let row = this.curVal[lastIdx]
                        arr.unshift(row);
                        this.curVal.splice(lastIdx, 1)
                        lastIdx -= 1;
                    }
                    this.curVal.splice(idx - 1, 0, ...arr);
                } else {
                    this.$message.warning(this.i18n('lineMovement','如果要多行移动，请选中连续的行！'));
                }

            } else {
                let row = this.selectRowLise[0];
                let idx = this.curVal.findIndex(item =>{
                    const itemId = item.ID_ ? item.ID_ : item.index_;
                    const rowId = row.ID_ ? row.ID_ : row.index_;
                    return itemId === rowId;
                });
                if (idx > 0) {
                    let select = this.curVal[idx];
                    this.curVal.splice(idx, 1);
                    this.curVal.splice(idx - 1, 0, select);
                }
            }
        },
        //下移
        downMove() {
            if (this.selectRowLise.length === 0) {
                this.$message.warning(this.i18n('oneRow','请至少选中一行数据！'));
                return;
            }
            if (this.selectRowLise.length > 1) {
                //多行移动
                let area = this.getContinuousIndex();
                if (area) {
                    let [idx, lastIdx] = area;
                    let arr = []
                    while (lastIdx >= idx) {
                        let row = this.curVal[lastIdx]
                        arr.unshift(row);
                        this.curVal.splice(lastIdx, 1)
                        lastIdx -= 1;
                    }
                    this.curVal.splice((area[1] + 1) - (area[1] - area[0]), 0, ...arr)
                } else {
                    this.$message.warning(this.i18n('lineMovement','如果要多行移动，请选中连续的行！'));
                }
            } else {
                //单行移动
                let row = this.selectRowLise[0];
                let idx = this.curVal.findIndex(item =>{
                    const itemId = item.ID_ ? item.ID_ : item.index_;
                    const rowId = row.ID_ ? row.ID_ : row.index_;
                    return itemId === rowId;
                });
                if (idx > -1 && idx < this.curVal.length - 1) {
                    let select = this.curVal[idx];
                    this.curVal.splice(idx, 1);
                    this.curVal.splice(idx + 1, 0, select);
                }
            }
        },
        //编辑
        edit() {
            if (this.selectRowLise.length !== 1) {
                this.$message.warning(this.i18n('oneRow','请至少选中一行数据！'));
                return;
            }
            this.subRow = this.selectRowLise[0];
            this.show = true
        },
        getContinuousIndex(type) {
            //获取连续的选中的行的idx，并且排序
            let {selectRowLise} = this;
            let arr = selectRowLise.map(select => {
                let idx = this.curVal.findIndex(item =>{
                    const itemId = item.ID_ ? item.ID_ : item.index_;
                    const selectId = select.ID_ ? select.ID_ : select.index_;
                    return itemId === selectId;
                });
                return {idx, row: select}
            }).sort((a, b) => {
                return a.idx - b.idx
            })

            //在上移的情况下 如果是第一行 无论是不是连续的 都不用上移了,同理下移动也是一样
            if ((type === 'up' && arr[0].idx === 0) || (type === 'down' && arr[arr.length - 1].idx === this.curVal.length - 1)) {
                return false;
            }

            //判断选中的是不是连续的数据
            let isTrue = true;
            for (let i = 0; i < arr.length; i++) {
                let item = arr[i];
                if (i !== arr.length - 1) {
                    if (item.idx + 1 === arr[i + 1].idx) {
                        continue
                    } else {
                        isTrue = false;
                        break;
                    }
                }
            }
            //如果是连续的选中，则返回选中的区间
            if (isTrue) {
                return [arr[0].idx, arr[arr.length - 1].idx];
            }
            return false
        },
        confirm(row) {
            let showRow = true
            this.curVal.forEach(res => {
                let id_ = res.ID_?res.ID_:res.index_;
                let id =  row.ID_?row.ID_:row.index_
                if (id_ == id) {
                    res = row;
                    showRow = false
                }
            })
            if (showRow) {
                this.curVal.push(row);
            }
            this.close()
        },
        close() {
            this.selectListAll = [];
            this.selectRowLise = [];
            this.show = false
        }
    },
}
</script>

<style scoped>
.m-rowChildren{
    padding:0.5rem;
    border-left: 1px solid rgb(228, 231, 237);
}
.m-rowChildren:first-child{
    border: none;
}
.sub-mobile-layer-container {
    position: fixed;
    inset: 0;
    width: calc(100% - 1rem);
    height: calc(100% - 1rem);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    background-color: #fff;
    margin: 0.5rem;
    box-sizing: border-box;
    box-shadow: 0rem 0rem 0.2rem 0rem #dce0;
    border-radius: 5px;
    border: 1px solid rgb(228, 231, 237);
    z-index: 998;
}

.sub-table-list-content {
    border: 1px solid rgb(228, 231, 237);
    scrollbar-width: none;
    -ms-overflow-style: none;
    background-color: white;
    overflow: auto;
    margin: 0rem 0.4rem 0.4rem 0.4rem;
}

.sub-table-list-checkbox {
    position: sticky;
    min-width: 2rem;
    min-height: 36px;
    width: 12rem;
    background: rgba(245, 247, 250, 1);
    border-bottom: 1px solid rgb(228, 231, 237);
    border-right: 1px solid rgb(228, 231, 237);
    left: 0;
    text-align: center;
    z-index: 1;
}

.sub-table-list-th {
    min-width: 10rem;
    height: 2rem;
    overflow: auto;
    text-align: center;
    background: rgba(245, 247, 250, 1);
    border-bottom: 1px solid rgb(228, 231, 237);
    border-right: 1px solid rgb(228, 231, 237);
}

.sub-table-list-line-th {
    border-bottom: 1px solid rgb(228, 231, 237);
    border-right: 1px solid rgb(228, 231, 237);
    padding: .5rem;
}
.sub-table-list-table tr:last-of-type .sub-table-list-line-th{
    border-bottom: none;
}
.sub-table-list-table {
    overflow-y: auto;
    border-collapse: collapse;

}

.sub-table-list-table ::-webkit-scrollbar {
    display: none;
}

.sub-empty {
    height: 7rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}

.sub-empty-img {
    height: 4rem;
    width: 8rem;
}

.sub-empty-name {
    font-size: 0.8rem;
    margin-top: 0.2rem;
    color: rgba(213, 221, 234, 1);
}
.m-rowChildren{
    display: flex;
}
.sub-table-list-line-th >>>.ant-input-canEdit,
.sub-table-list-line-th >>>.uv-border,
sub-table-list-line-th >>>.rx-select-disabled,
sub-table-list-line-th >>>.rx-disabled,
sub-table-list-line-th >>>.m-empty{
    background: transparent!important;
}
</style>
